package abio

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

var defaultOption = Options{
	MaxSize:  1 << 20, //默认文件最大值,1MB
	SaveDays: 3,
}

//Options io 对象的选项
type Options struct {
	MaxSize  int64 //文件的最大值,当达到MaxSize时,自动备份文件
	SaveDays int   //文件保存天数
}

func backUpPackage(ab *AbFile) error {
	var err error
	if FileSize(ab.file) < ab.option.MaxSize {
		return nil
	}
	var (
		dirName, fileName, ext, fn1, fullName, backUpDirName string
	)
	dirName, fileName = filepath.Split(ab.absPathName)
	ext = filepath.Ext(fileName)
	fn1 = strings.Replace(fileName, ext, "", -1)
	n := 0
	for {
		backUpDirName = filepath.Join(dirName, fmt.Sprintf("%s%s", fn1, time.Now().Local().Format("20060102")))
		fullName = filepath.Join(backUpDirName, fmt.Sprintf("%s%06d%s", fn1, n, ext))
		if !FileExists(fullName) {
			if err = os.MkdirAll(backUpDirName, 0755); err != nil && err != os.ErrExist {
				return err
			}
			break
		}
		n++
	}
	if err = CopyFileTo(fullName, ab.file); err != nil {
		return err
	}
	if err = ab.file.Truncate(0); err != nil {
		return err
	}
	return nil
}

func delDirForDays(ab *AbFile) {
	dirName := filepath.Dir(ab.absPathName) //当前文件目录
	ext := filepath.Ext(ab.file.Name())
	baseFileName := strings.Replace(filepath.Base(ab.file.Name()), ext, "", -1)
	timeBefore := time.Now().AddDate(0, 0, -1*ab.option.SaveDays)
	ifs, _ := ioutil.ReadDir(dirName)
	for _, fileInfo := range ifs {
		if !fileInfo.IsDir() {
			continue
		}
		dateDay := strings.Replace(fileInfo.Name(), baseFileName, "", -1)
		t, er := time.ParseInLocation("20060102", dateDay, time.Local)
		if er != nil {
			continue
		}
		if t.After(timeBefore) {
			continue
		}
		fullPath := filepath.Join(dirName, fileInfo.Name())
		_ = os.RemoveAll(fullPath)
	}
}

// FileExists reports whether the named file or directory exists.
func FileExists(name string) bool {
	if _, err := os.Stat(name); err != nil {
		return !os.IsNotExist(err)
	}
	return true
}

func FileSize(f *os.File) int64 {
	st, err := f.Stat()
	if err != nil {
		panic(err)
	}
	return st.Size()
}

func CopyFileTo(dstName string, f *os.File) (err error) {
	dst, e := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0755)
	if e != nil {
		return e
	}
	defer func() {
		_ = dst.Close()
	}()
	//设置偏移量,从文件开头读取
	_, _ = f.Seek(0, 0)
	if _, err = io.Copy(dst, f); err != nil {
		return
	}
	return
}

//获取文件绝对路径
func AbsPathOfFile(name string) string {
	str, err := filepath.Abs(name)
	if err != nil {
		panic(err)
	}
	return str
}

//TouchFile If the file does not exist, it is created automatically.
//Do not do anything if the file already exists.
func TouchFile(fileName string) error {
	if FileExists(fileName) {
		return nil
	}
	dir := filepath.Dir(fileName)
	if err := os.MkdirAll(dir, 0755); err != nil && err != os.ErrExist {
		return err
	}
	f, err := os.Create(fileName)
	if err != nil {
		return err
	}
	return f.Close()
}
